package cn.kinlon.emoticon_set;

import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;
import android.widget.Button;
import android.widget.ScrollView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import cn.kinlon.emoticon_set.bean.Bean;
import cn.kinlon.emoticon_set.bean.Bean0;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.commons.io.FileUtils;

import javax.net.ssl.HttpsURLConnection;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.zip.GZIPInputStream;

public class MainActivity extends AppCompatActivity {
    private final Consumer<HttpsURLConnection> rp_json = conn -> {
        conn.setConnectTimeout(100000);
        conn.setReadTimeout(100000);

        conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7");
        conn.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
        conn.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9");
        conn.setRequestProperty("Cache-Control", "max-age=0");
        conn.setRequestProperty("Sec-Ch-Ua", "\"Chromium\";v=\"118\", \"Microsoft Edge\";v=\"118\", \"Not=A?Brand\";v=\"99\"");
        conn.setRequestProperty("Sec-Ch-Ua-Mobile", "?0");
        conn.setRequestProperty("Sec-Ch-Ua-Platform", "Windows");
        conn.setRequestProperty("Sec-Fetch-Dest", "document");
        conn.setRequestProperty("Sec-Fetch-Mode", "navigate");
        conn.setRequestProperty("Sec-Fetch-Site", "none");
        conn.setRequestProperty("Sec-Fetch-User", "?1");
        conn.setRequestProperty("Upgrade-Insecure-Requests", "1");
        conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.76");
    };
    private final Consumer<HttpsURLConnection> rp_img = conn -> {
        conn.setConnectTimeout(100000);
        conn.setReadTimeout(100000);

        conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7");
        conn.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
        conn.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9");
        conn.setRequestProperty("Sec-Ch-Ua", "\"Chromium\";v=\"118\", \"Microsoft Edge\";v=\"118\", \"Not=A?Brand\";v=\"99\"");
        conn.setRequestProperty("Sec-Ch-Ua-Mobile", "?0");
        conn.setRequestProperty("Sec-Ch-Ua-Platform", "Windows");
        conn.setRequestProperty("Sec-Fetch-Dest", "document");
        conn.setRequestProperty("Sec-Fetch-Mode", "navigate");
        conn.setRequestProperty("Sec-Fetch-Site", "none");
        conn.setRequestProperty("Sec-Fetch-User", "?1");
        conn.setRequestProperty("Upgrade-Insecure-Requests", "1");
        conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.76");
    };
    private Button button;
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = findViewById(R.id.btn01);
        textView = findViewById(R.id.tv01);

        button.setOnClickListener(view -> {
            if (!button.isEnabled()) return;
            try {
                textView.setText("");
                btnOnClick();
            } catch (Exception e) {
                log(e.toString());
                throw new RuntimeException(e);
            }
        });

        ScrollView scrollView = findViewById(R.id.sv01);
        scrollView.getViewTreeObserver().addOnGlobalLayoutListener(
                () -> scrollView.post(() -> scrollView.fullScroll(ScrollView.FOCUS_DOWN))
        );
    }

    @Override
    protected void onPostResume() {
        super.onPostResume();
        //if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        if (!Environment.isExternalStorageManager()) {
            Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
            // 动态授权，文件读写
            this.startActivity(intent);
            //return;
        }
        //}
    }

    private void log(String log) {
        runOnUiThread(() -> {
            textView.append(LocalDateTime.now().toString());
            textView.append("=>");
            textView.append(log);
            textView.append("\n");
        });
    }

    private void btnOnClick() {
        // 任务放入线程，避免主线程未响应
        Thread t = new Thread(() -> {
            try {
                runOnUiThread(() -> button.setEnabled(false));
                String urlPath = "https://bbs-api-static.mihoyo.com/misc/api/emoticon_set";
                // 模拟访问获取数据
                log("获取Json数据");
                byte[] data = connect(urlPath, rp_json);
                // 数据解压
                log("解压Json数据");
                data = unGZip(data);
                // 字符编码转换
                log("Json字符串转码");
                // 有emoji字符作为文件名
                //data = StringUtils.toEncodedString(data, Charset.forName("GBK")).getBytes(StandardCharsets.UTF_8);
                // 清空目录
                log("清空目录");
                String file_path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
                        .getAbsolutePath() + "/mihoyo/";
                FileUtils.deleteQuietly(new File(file_path));
                // 写入文件
                log("导出Json到文件");
                saveFile(file_path + "emoticon_set/emoticon_set.json", data);
                // 解析Json
                log("解析Json数据");
                Bean0 bean0 = parseJson(new String(data, StandardCharsets.UTF_8));
                // 解析Bean
                log("下载表情数据");
                List<Bean> list = parseBean(bean0);
                // 导出图片数据
                log("导出图片到文件夹");
                savePNG(file_path + "emoticon_set/png", list);
                log("完成");
            } catch (Exception e) {
                log(e.toString());
                throw new RuntimeException(e);
            } finally {
                runOnUiThread(() -> button.setEnabled(true));
            }
        });
        t.start();
    }

    private Bean0 parseJson(String json) {
        Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
        return gson.fromJson(json, Bean0.class);
    }

    private List<Bean> parseBean(Bean0 bean) {
        List<Bean> list = new ArrayList<>();
        bean.getData().getList().forEach(e -> {
            int id1 = e.getId();
            String name1 = e.getName();
            e.getList().forEach(f -> {
                int id2 = f.getId();
                String name2 = f.getName();
                String url = f.getIcon();
                int sortOrder = f.getSort_order();
                byte[] img;
                try {
                    img = connect(url, rp_img);
                } catch (Exception ex) {
                    throw new RuntimeException(ex);
                }
                Bean b = new Bean(id1, name1, sortOrder, id2, name2, url, img);
                list.add(b);
            });
        });
        return list;
    }

    private void savePNG(String rootPath, List<Bean> data) throws Exception {
        for (Bean e : data) {
            //int id_1 = e.getId_1();
            String name_1 = e.getName_1();
            //int sortOrder = e.getSortOrder();
            //int id_2 = e.getId_2();
            String name_2 = e.getName_2();
            //String url = e.getUrl();
            byte[] icon = e.getIcon();

            saveFile(rootPath + "/" + name_1 + "/" + name_2 + ".png", icon);
            //saveFile(rootPath + "/byName/" + name_1 + "/" + name_2 + ".png", icon);
            //saveFile(rootPath + "/byIdName/" + name_1 + "/" + name_2 + ".png", icon);
            //saveFile(rootPath + "/byId/" + name_1 + "/" + name_2 + ".png", icon);
        }
    }

    private byte[] connect(String urlPath, Consumer<HttpsURLConnection> fun) throws Exception {
        log(urlPath);
        URL url = new URL(urlPath);
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        conn.setDoOutput(false);
        conn.setRequestMethod("GET");
        fun.accept(conn);
        conn.connect();
        if (conn.getResponseCode() == 200) {
            try (BufferedInputStream bi = new BufferedInputStream(conn.getInputStream())) {
                return bi.readAllBytes();
            }
        }
        return new byte[]{};
    }

    private byte[] unGZip(byte[] encode) throws Exception {
        try (GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(encode))) {
            return gzipInputStream.readAllBytes();
        }
    }

    private void saveFile(String filePath, byte[] data) throws Exception {
        log(filePath);
        Path path = Paths.get(filePath);
        Files.createDirectories(path.getParent());
        Files.write(path, data,
                StandardOpenOption.WRITE,
                StandardOpenOption.CREATE_NEW,
                StandardOpenOption.TRUNCATE_EXISTING);
    }
}
